#include "./parts.h"
#include "../../device/gpio.h"


namespace driver {

using namespace device::gpio;

using STEAM_HEAT = PB<0>; // TIM3_CH3
using WATER_HEAT = PB<9>; // TIM4_CH4

using CLEAN_VALVE = PB<10>;
using WATER_VALVE = PB<11>;
using CLEAN_PUMP = PB<12>;
using WATER_PUMP = PB<13>;
using STEAM_VALVE = PB<14>;
using STEAM_PUMP = PB<15>;

using RO_EXIT_VALVE = PC<8>;
using BUCKET2_PUMP = PC<9>;
using BUCKET1_PUMP = PC<10>;
using RO_ENTER_VALVE = PC<11>;
using STIR_MOTOR = PC<12>;
using DROP_VALVE = PC<13>;

static bool steamHeatFlag = false;
static bool waterHeatFlag = false;

static bool cleanValveFlag = false;
static bool waterValveFlag = false;
static bool cleanPumpFlag = false;
static bool waterPumpFlag = false;

static bool steamValveFlag = false;
static bool steamPumpFlag = false;

static bool roExitValveFlag = false;
static bool bucket2PumpFlag = false;
static bool bucket1PumpFlag = false;
static bool roEnterValveFlag = false;
static bool stirMotorFlag = false;
static bool dropValveFlag = false;

Parts::Parts() {
    RCC->APB2ENR |= RCC_APB2ENR_IOPBEN |
        RCC_APB2ENR_IOPCEN;
    RCC->APB1ENR |= RCC_APB1ENR_TIM3EN |
        RCC_APB1ENR_TIM4EN;

    config_af_pp_out<STEAM_HEAT, WATER_HEAT>();
    config_pp_out<
        CLEAN_VALVE, WATER_VALVE, 
        CLEAN_PUMP, STEAM_PUMP, 
        STEAM_VALVE, WATER_PUMP,
        RO_ENTER_VALVE, BUCKET2_PUMP,
        BUCKET1_PUMP, RO_EXIT_VALVE,
        STIR_MOTOR, DROP_VALVE
    >();

    TIM3->CR1 = 0x00;
    TIM3->CR2 = 0x00;
    TIM3->PSC = 7200 - 1;
    TIM3->ARR = 1000 - 1;
    TIM3->CCR3 = 0;
    TIM3->CCMR2 = 0x0060;
    TIM3->CCER = 0x0100;
    TIM3->EGR = 0x01;
    TIM3->CR1 = 0x01;

    TIM4->CR1 = 0x00;
    TIM4->CR2 = 0x00;
    TIM4->PSC = 7200 - 1;
    TIM4->ARR = 1000 - 1;
    TIM4->CCR4 = 0;
    TIM4->CCMR2 = 0x6000;
    TIM4->CCER = 0x1000;
    TIM4->EGR = 0x01;
    TIM4->CR1 = 0x01;
}

uint16_t Parts::status() {
    return waterHeatFlag |
        (steamHeatFlag << 1) |
        (waterPumpFlag << 2) |
        (cleanPumpFlag << 3) |
        (waterValveFlag << 4) |
        (cleanValveFlag << 5) |
        (steamPumpFlag << 6) |
        (steamValveFlag << 7) |
        (bucket1PumpFlag << 8) |
        (bucket2PumpFlag << 9) |
        (roEnterValveFlag << 10) |
        (roExitValveFlag << 11) |
        (stirMotorFlag << 12) |
        (dropValveFlag << 13)
        ;
}

void Parts::steam_heat_ctrl(uint8_t val) {
    TIM3->CCR3 = val * 10;
    steamHeatFlag = val != 0;
}

void Parts::water_heat_ctrl(uint8_t val) {
    TIM4->CCR4 = val * 10;
    waterHeatFlag = val != 0;
}

void Parts::water_pump_open() {
    WATER_PUMP::set();
    waterPumpFlag = true;
}

void Parts::water_pump_close() {
    WATER_PUMP::clr();
    waterPumpFlag = false;
}

void Parts::clean_pump_open() {
    CLEAN_PUMP::set();
    cleanPumpFlag = true;
}

void Parts::clean_pump_close() {
    CLEAN_PUMP::clr();
    cleanPumpFlag = false;
}

void Parts::water_valve_open() {
    WATER_VALVE::set();
    waterValveFlag = true;
}

void Parts::water_valve_close() {
    WATER_VALVE::clr();
    waterValveFlag = false;
}

void Parts::clean_valve_open() {
    CLEAN_VALVE::set();
    cleanValveFlag = true;
}

void Parts::clean_valve_close() {
    CLEAN_VALVE::clr();
    cleanValveFlag = false;
}

void Parts::steam_pump_open() {
    STEAM_PUMP::set();
    steamPumpFlag = true;
}

void Parts::steam_pump_close() {
    STEAM_PUMP::clr();
    steamPumpFlag = false;
}

void Parts::steam_valve_open() {
    STEAM_VALVE::set();
    steamValveFlag = true;
}

void Parts::steam_valve_close() {
    STEAM_VALVE::clr();
    steamValveFlag = false;
}

void Parts::bucket1_pump_open() {
    BUCKET1_PUMP::set();
    bucket1PumpFlag = true;
}

void Parts::bucket1_pump_close() {
    BUCKET1_PUMP::clr();
    bucket1PumpFlag = false;
}

void Parts::bucket2_pump_open() {
    BUCKET2_PUMP::set();
    bucket2PumpFlag = true;
}

void Parts::bucket2_pump_close() {
    BUCKET2_PUMP::clr();
    bucket2PumpFlag = false;
}

void Parts::ro_exit_valve_open() {
    RO_EXIT_VALVE::set();
    roExitValveFlag = true;
}

void Parts::ro_exit_valve_close() {
    RO_EXIT_VALVE::clr();
    roExitValveFlag = false;
}

void Parts::ro_enter_valve_open() {
    RO_ENTER_VALVE::set();
    roEnterValveFlag = true;
}

void Parts::ro_enter_valve_close() {
    RO_ENTER_VALVE::clr();
    roEnterValveFlag = false;
}

void Parts::stir_motor_open() {
    STIR_MOTOR::set();
    stirMotorFlag = true;
}

void Parts::stir_motor_close() {
    STIR_MOTOR::clr();
    stirMotorFlag = false;
}

void Parts::drop_valve_open() {
    DROP_VALVE::set();
    dropValveFlag = true;
}

void Parts::drop_valve_close() {
    DROP_VALVE::clr();
    dropValveFlag = false;
}


}
